package com.train.common.online.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.train.common.core.annotation.MyDataSourceResolver;
import com.train.common.core.base.dao.BaseDaoMapper;
import com.train.common.core.base.service.BaseService;
import com.train.common.core.constant.ApplicationConstant;
import com.train.common.core.object.TokenData;
import com.train.common.core.util.DefaultDataSourceResolver;
import com.train.common.core.util.RedisKeyUtil;
import com.train.common.online.dao.OnlineFormUserExtMapper;
import com.train.common.online.model.OnlineFormUserExt;
import com.train.common.online.service.OnlineFormUserExtService;
import com.train.common.sequence.wrapper.IdGeneratorWrapper;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

/**
 * 在线表单用户数据操作服务类。
 *
 * @author xulei
 * @date 2025-03-07
 */
@Slf4j
@MyDataSourceResolver(
        resolver = DefaultDataSourceResolver.class,
        intArg = ApplicationConstant.COMMON_FLOW_AND_ONLINE_DATASOURCE_TYPE)
@Service("onlineFormUserExtService")
public class OnlineFormUserExtServiceImpl extends BaseService<OnlineFormUserExt, Long> implements OnlineFormUserExtService {

    @Autowired
    private IdGeneratorWrapper idGenerator;
    @Autowired
    private OnlineFormUserExtMapper onlineFormUserExtMapper;
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 返回当前Service的主表Mapper对象。
     *
     * @return 主表Mapper对象。
     */
    @Override
    protected BaseDaoMapper<OnlineFormUserExt> mapper() {
        return onlineFormUserExtMapper;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public OnlineFormUserExt saveNewOrUpdate(OnlineFormUserExt data) {
        RBucket<String> bucket = redissonClient.getBucket(RedisKeyUtil.makeUserFormExtKey(data.getOnlineFormId()));
        if (bucket.isExists()) {
            bucket.delete();
        }
        if (data.getId() == null) {
            onlineFormUserExtMapper.insert(this.buildDefaultValue(data));
        } else {
            onlineFormUserExtMapper.updateById(this.buildDefaultValue(data));
        }
        return data;
    }

    @Override
    public OnlineFormUserExt getByFormId(Long formId) {
        RBucket<String> bucket = redissonClient.getBucket(RedisKeyUtil.makeUserFormExtKey(formId));
        if (bucket.isExists()) {
            return JSON.parseObject(bucket.get(), OnlineFormUserExt.class);
        }
        LambdaQueryWrapper<OnlineFormUserExt> qw = new LambdaQueryWrapper<>();
        qw.eq(OnlineFormUserExt::getOnlineFormId, formId);
        qw.eq(OnlineFormUserExt::getUserId, TokenData.takeFromRequest().getUserId());
        OnlineFormUserExt data = onlineFormUserExtMapper.selectOne(qw);
        if (data == null) {
            data = new OnlineFormUserExt();
            data.setOnlineFormId(formId);
            data.setUserId(TokenData.takeFromRequest().getUserId());
        }
        bucket.set(JSON.toJSONString(data), 10, TimeUnit.MINUTES);
        return data;
    }

    private OnlineFormUserExt buildDefaultValue(OnlineFormUserExt data) {
        if (data.getId() == null) {
            data.setId(idGenerator.nextLongId());
        }
        data.setUserId(TokenData.takeFromRequest().getUserId());
        return data;
    }
}
